package com.meritdata.cloud.data.standard.table.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.UUID;

import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.RegExUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.meritdata.cloud.data.base.Page;
import com.meritdata.cloud.data.base.ResultData;
import com.meritdata.cloud.data.standard.table.dao.IDictCommonValueDao;
import com.meritdata.cloud.data.standard.table.dao.IDictPartStructDao;
import com.meritdata.cloud.data.standard.table.dao.IDictPartValueDao;
import com.meritdata.cloud.data.standard.table.entity.TdDictCommonValue;
import com.meritdata.cloud.data.standard.table.entity.TdDictPartStruct;
import com.meritdata.cloud.data.standard.table.entity.TdDictPartValue;
import com.meritdata.cloud.data.standard.table.service.IDictValueService;

@Service
public class DictValueService implements IDictValueService {

	@Autowired
	private IDictPartStructDao dictPartStructDao;

	@Autowired
	private IDictPartValueDao dictPartValueDao;

	@Autowired
	private IDictCommonValueDao dictCommonValueDao;

	@Override
	public ResultData page(Long dictId, int pageNum, int pageSize, String name) {
		ResultData result = new ResultData();

		Map<String, Object> data = new HashMap<>();
		result.setData(data);

		List<TdDictPartStruct> partStruct = dictPartStructDao.findEqualField("dictId", dictId);
		Page<TdDictCommonValue> pageCommon;
		if (StringUtils.isBlank(name)) {
			pageCommon = dictCommonValueDao.pageHql(
					"from TdDictCommonValue t where t.dictId = ? order by t.commonName asc", pageNum, pageSize, dictId);
		} else {
			pageCommon = dictCommonValueDao.pageHql(
					"from TdDictCommonValue t where t.dictId = ? and t.commonName like ? order by t.commonName asc",
					pageNum, pageSize, dictId, "%" + name.trim() + "%");
		}

		List<Map<String, Object>> names = new ArrayList<>();
		data.put("names", names);
		Map<String, Object> map1 = new HashMap<>();
		map1.put("name", "common-id");
		map1.put("value", "通用码Id");
		names.add(map1);
		Map<String, Object> map2 = new HashMap<>();
		map2.put("name", "common-code");
		map2.put("value", "通用码编码");
		names.add(map2);
		Map<String, Object> map3 = new HashMap<>();
		map3.put("name", "common-name");
		map3.put("value", "显示名称");
		names.add(map3);
		if (!CollectionUtils.isEmpty(partStruct)) {
			for (TdDictPartStruct tdDictPartStruct : partStruct) {
				long id = tdDictPartStruct.getId();
				Map<String, Object> map4 = new HashMap<>();
				map4.put("name", id + "-id");
				map4.put("value", id);
				names.add(map4);
				Map<String, Object> map5 = new HashMap<>();
				map5.put("name", id + "-name");
				map5.put("value", tdDictPartStruct.getName());
				names.add(map5);
			}
		}
		data.put("values", convertCommonValuePage(pageCommon, partStruct));
		return result;
	}

	private Page<Map<String, Object>> convertCommonValuePage(Page<TdDictCommonValue> pageCommon,
			List<TdDictPartStruct> partStruct) {
		Page<Map<String, Object>> page = new Page<>();
		page.setTotalCount(pageCommon.getTotalCount());
		page.setPageSize(pageCommon.getPageSize());
		page.setPageNum(pageCommon.getPageNum());

		List<Map<String, Object>> data = new ArrayList<>();
		page.setDatas(data);

		List<TdDictCommonValue> values = pageCommon.getDatas();
		if (CollectionUtils.isEmpty(values)) {
			return page;
		}

		List<TdDictPartValue> partValues = null;
		if (!CollectionUtils.isEmpty(partStruct)) {
			partValues = listPartValue(values);
		}

		Map<String, TdDictPartValue> partValueMapping = new HashMap<>();
		if (!CollectionUtils.isEmpty(partValues)) {
			for (TdDictPartValue tdDictPartValue : partValues) {
				partValueMapping.put(tdDictPartValue.getCommonCode() + tdDictPartValue.getPartId(), tdDictPartValue);
			}
		}

		for (TdDictCommonValue tdDictCommonValue : values) {
			Map<String, Object> item = new HashMap<>();
			item.put("common-id", tdDictCommonValue.getId());
			item.put("common-code", tdDictCommonValue.getCommonCode());
			item.put("common-name", tdDictCommonValue.getCommonName());
			if (!CollectionUtils.isEmpty(partStruct)) {
				for (TdDictPartStruct tdDictPartStruct : partStruct) {
					long id = tdDictPartStruct.getId();
					Long valId = null;
					String valName = null;
					TdDictPartValue tdDictPartValue = partValueMapping.get(tdDictCommonValue.getCommonCode() + id);
					if (tdDictPartValue != null) {
						valId = tdDictPartValue.getId();
						valName = tdDictPartValue.getCode();
					}
					item.put(id + "-id", valId);
					item.put(id + "-name", valName);
				}
			}

			data.add(item);
		}

		return page;
	}

	private List<TdDictPartValue> listPartValue(List<TdDictCommonValue> commonValues) {
		if (CollectionUtils.isEmpty(commonValues)) {
			return null;
		}
		Object[] commonCodes = new Object[commonValues.size()];
		String[] questions = new String[commonValues.size()];
		int i = 0;
		for (TdDictCommonValue tdDictPartStruct : commonValues) {
			commonCodes[i] = tdDictPartStruct.getCommonCode();
			questions[i] = "?";
			i++;
		}

		List<TdDictPartValue> partValues = dictPartValueDao.findHql(
				"from TdDictPartValue t where t.commonCode in (" + StringUtils.join(questions, ",") + ")", commonCodes);

		return partValues;
	}

	@Override
	@Transactional
	public ResultData delete(Long commonId) {
		ResultData result = new ResultData();
		TdDictCommonValue commonValue = dictCommonValueDao.findOne(commonId);
		if (commonValue == null) {
			result.setStatus(false);
			result.setMsg("码值已不存在");
			return result;
		}

		int delete = dictPartValueDao.deleteEqualField("commonCode", commonValue.getCommonCode());
		delete = dictCommonValueDao.delete(commonId);
		result.setStatus(delete > 0);
		return result;
	}

	@Override
	@Transactional
	public ResultData modify(List<Map<String, Object>> dictValues, Long dictId, String userId) {
		ResultData result = new ResultData();

		for (Map<String, Object> dictValue : dictValues) {
			Long commonId = dictValue.get("common-id") == null ? null
					: Long.valueOf(String.valueOf(dictValue.get("common-id")));
			String commonName = (String) dictValue.get("common-name");
			TdDictCommonValue commonValue;
			if (commonId == null && StringUtils.isBlank(commonName)) {
				continue;
			}
			if (commonId == null) {
				// 公共码新增
				commonValue = new TdDictCommonValue();
				commonValue.setCommonCode(RegExUtils.replaceAll(UUID.randomUUID().toString(), "-", ""));
				commonValue.setCommonName(commonName);
				commonValue.setCreateTime(new Date());
				commonValue.setCreator(userId);
				commonValue.setDictId(dictId);
				dictCommonValueDao.save(commonValue);
			} else {
				commonValue = dictCommonValueDao.findOne(commonId);
				if (commonValue == null) {
					continue;
				}
				if (StringUtils.isNotBlank(commonName)) {
					// 公共码更新
					commonValue.setCommonName(commonName);
					commonValue.setReviserId(userId);
					commonValue.setUpdateTime(new Date());
					dictCommonValueDao.update(commonValue);
				}
			}

			Set<Long> partIds = new HashSet<>();
			// 修改业务码
			for (Entry<String, Object> entry : dictValue.entrySet()) {
				String key = entry.getKey();
				if (StringUtils.startsWith(key, "common")) {
					continue;
				}
				String[] split = StringUtils.split(key, "-");
				if (split.length != 2) {
					continue;
				}
				Long partId = Long.valueOf(split[0]);

				if (partIds.contains(partId)) {
					continue;
				}
				partIds.add(partId);

				Long idValue = dictValue.get(partId + "-id") == null ? null
						: Long.valueOf(String.valueOf(dictValue.get(partId + "-id")));
				String nameValue = (String) dictValue.get(partId + "-name");
				if (StringUtils.isBlank(nameValue)) {
					continue;
				}
				if (idValue == null) {
					// 业务码新增
					TdDictPartValue partValue = new TdDictPartValue();
					partValue.setCode(nameValue);
					partValue.setCommonCode(commonValue.getCommonCode());
					partValue.setCreateTime(new Date());
					partValue.setCreator(userId);
					partValue.setPartId(partId);
					dictPartValueDao.save(partValue);
				} else {
					// 业务码修改
					TdDictPartValue partValue = dictPartValueDao.findOne(idValue);
					if (partValue == null) {
						continue;
					}
					partValue.setCode(nameValue);
					partValue.setReviserId(userId);
					partValue.setUpdateTime(new Date());
					dictPartValueDao.update(partValue);
				}
			}
		}
		return result;
	}

}
